import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { snowflake } from 'src/util/Snowflake';

/**
 * 基础服务类
 * @param T 模型类型
 */
@Injectable()
export abstract class BaseService<T> {

  /**
   * @param model 模型类型
   * @param populates 是否有关联查询
   */
  protected constructor(
    protected readonly model: Model<T>,
    protected readonly populates: any[] = [],
  ) { }



  /** 创建数据 */
  async create(createDto: any) {
    createDto.isDel = false;
    createDto.createTime = new Date();
    createDto.sortCode = createDto.sortCode ?? 0;
    const createdEntity = new this.model(createDto);
    createdEntity._id = snowflake.nextId();
    return createdEntity.save();
  }

  /** 更新数据 */
  async update(id: number, updateDto: any): Promise<T | null> {
    delete updateDto._id;
    return this.model.findByIdAndUpdate(id, updateDto, { new: true }).exec();
  }

  /** 软删除数据 */
  async softDelete(id: number): Promise<T | null> {
    return this.model.findByIdAndUpdate(id, { isDel: true }, { new: true }).exec();
  }

  /** 硬删除数据 */
  async hardDelete(id: number): Promise<T | null> {
    return this.model.findByIdAndDelete(id).exec();
  }

  /** 获取所有数据 */
  async findAll(): Promise<T[]> {
    const myQuery = this.model.find({ isDel: false });
    if (this.populates.length > 0) {
      return myQuery.populate(this.populates).exec();
    }
    return myQuery.exec();
  }

  /** 根据id获取数据 */
  async findById(id: number): Promise<T | null> {
    const myQuery = this.model.findOne({ _id: id, isDel: false });

    if (this.populates.length > 0) {
      return myQuery.populate(this.populates).exec();
    }
    return myQuery.exec();
  }

  /** 根据条件查询数据 */
  async findWhereList(where: any): Promise<T[]> {
    const mySort = where.sort ?? {}
    const myQuery = this.model.find(where).sort(mySort);
    let dataList = null;

    if (this.populates.length > 0) {
      dataList = myQuery.populate(this.populates).exec();
    } else {
      dataList = myQuery.exec();
    }
    return dataList;
  }

  /** 根据条件查询数据 */
  async findWhereOne(where: any): Promise<T> {
    const myQuery = this.model.findOne(where);
    if (this.populates.length > 0) {
      return myQuery.populate(this.populates).exec();
    }
    return myQuery.exec();
  }

  /** 分页查询 */
  findPage(pageInput: any) {

    const where = {
      isDel: false,
      ...(pageInput.query ?? {}),
    };

    pageInput.sorter = pageInput.sorter ?? {};

    console.log(111, pageInput);

    const myquery = this.model.find(where)
      .skip((pageInput.page - 1))
      .limit(pageInput.limit)
      .sort(pageInput.sorter as any);

    if (this.populates.length > 0) {
      return myquery.populate(this.populates).exec();
    }
    return myquery.exec();
  }

  /** 分页统计数量 */
  count(query: any) {
    try {
      const where = {
        isDel: false,
        ...(query ?? {}),
      };
      return this.model.countDocuments(where).exec();
    } catch (_error) {
      return 0;
    }
   
  }
}
